<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div style="position:relative;width:500px;height:400px;text-align:center;">
    <video controls="controls" autoplay="autoplay"
           style="width:100%;height:100%;"
           src="https://www.zhangxinxu.com/study/201709/video.mp4">
        Your browser does not support the video tag.
    </video>
    <canvas id="canvas" width="500" height="400"
            style="position:absolute;top:0;left:0;">
        您的浏览器不支持canvas标签。
    </canvas>
    <input id="txt" type="text">
    <input type="button" value="发送" onclick="pushTM()">
</div>
<script>
    function Barrage(canvas) {
        this.canvas = document.getElementById(canvas);
        let rect = this.canvas.getBoundingClientRect();
        this.w = rect.right - rect.left;
        this.h = rect.bottom - rect.top;
        this.ctx = this.canvas.getContext('2d');
        this.ctx.font = '20px Microsoft YaHei';
        this.barrageList = [];
        this.draw = this.draw.bind(this);
    }

    Barrage.prototype.shoot = function (value) {
        let top = this.getTop();
        let color = this.getColor();
        let offset = this.getOffset();
        let width = Math.ceil(this.ctx.measureText(value).width);

        let barrage = {
            value: value,
            top: top,
            left: this.w,
            color: color,
            offset: offset,
            width: width
        }
        this.barrageList.push(barrage);
    }

    Barrage.prototype.draw = function () {
        if (this.barrageList.length) {
            this.ctx.clearRect(0, 0, this.w, this.h);
            for (let i = 0; i < this.barrageList.length; i++) {
                let b = this.barrageList[i];
                if (b.left + b.width <= 0) {
                    this.barrageList.splice(i, 1);
                    i--;
                    continue;
                }
                b.left -= b.offset;
                this.drawText(b);
            }
        }
        requestAnimationFrame(this.draw);
    }

    Barrage.prototype.drawText = function (barrage) {
        this.ctx.fillStyle = barrage.color;
        this.ctx.fillText(barrage.value, barrage.left, barrage.top);
    }

    Barrage.prototype.getColor = function () {
        return '#' + Math.floor(Math.random() * 0xffffff).toString(16);

    }

    Barrage.prototype.getTop = function () {
        return Math.floor(Math.random() * (this.h - 30)) + 30;

    }

    Barrage.prototype.getOffset = function () {
        return +(Math.random() * 4).toFixed(1) + 1;

    }

    let barrage = new Barrage('canvas');


    const textList = ['弹幕', '666', '233333333',
        'javascript', 'html', 'css', '前端框架', 'Vue', 'React',
        'Angular', '测试弹幕效果'
    ];

    function pushTM() {
        console.log('pushTM');
        let dom = document.getElementById('txt');
        let txt = dom.value;
        barrage.shoot(txt);
        dom.value = '';
    }

    window.onload = function () {
        barrage.draw();
        textList.forEach((t) => {
            barrage.shoot(t);
        })
    }


</script>
</body>
</html>